<!DOCTYPE html>
<html lang="en" dir="auto">

<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="index, follow">
<title>Noise Contrastive Estimation | WangJV Blog</title>
<meta name="keywords" content="unsupervised learning, 对比学习">
<meta name="description" content="1. 动机
在无监督学习时，我们往往都需要处理维度非常大的数据。例如无监督学习的一个经典案例：图像生成。对于一个尺寸为 $1920 \times 1080$ 的图片，其像素总量为 $2073600$，生成一张这样的照片时，我们需要对一个维度为 $2073600$ 的随机分布建模和采样。这些维度之间不可能是完全独立的，这个原因很显然，如果所有的维度完全独立，生成的数据就是完全随机的，不会包含任何信息。相邻像素的颜色、纹理高度相关，真正需要被建模的自由度远小于像素个数
可以说，我们希望通过无监督学习学习到的数据之间的规律，就建模在数据维度之间的约束中，或者换一个更常用的说法，数据之间的规律。由于数据维度之间约束的存在，数据的维度一定是小于（甚至可以说远远小于）其随机向量的维度。我们希望建模的数据事实上存在于一个高维空间上的流形上，而无监督学习实质上是通过神经网络，建模这个高位空间中数据分布的流形。
有了上面的理解，原本的如何从数据中挖掘关系这个问题就被转换为如何对数据所在的流形建模。这个问题并不容易，流形的复杂性和高维数据的稀疏性都给建模带来了挑战。目前一个主流的思路是通过概率分布对流形建模。显然，概率分布可以很方便的表达流形上的几何结构；对于一个维度为 $d$ 的概率分布，可以理解为一个从 $R^d \to R$ 的映射，当然这个映射需要满足非负和归一化。那么对于不属于流形上的点，映射到 $0$ 就好了。当然，概率分布带给我们的好处远不止于此：

概率分布本身可以很方便的处理噪声，可以很方便的用于处理真实的，带噪声的真实数据。
概率分布的采样和优化十分方便，有很多现成的研究成果
概率分布本身赋予流形一个 “软边界”。这让模型的泛化能力有保障。

但是概率模型依然不是完美的。一般而言，我们假设存在一个理想分布 $p_d(x)$，它表达了完美的，真实的数据的分布。这是一个 “可望而不可达” 的理想分布，我们所用的数据集 $x_1, x_2, \cdots x_n$ 可以认为从分布 $p_d(x)$ 中做的采样。（一种柏拉图式的哲学）。我们希望可以通过一个受到参数 $\theta$ 控制的模型分布 $p(x, \theta)$ 来逼近和代替真实分布 $p_d(x)$。
我们的神经网络不可能直接建模非归一化模型，模型本身几乎一定是非归一化的。假设我们只能建模一个非归一化模型 $q(x\mid \theta)$，则需要通过归一化系数将其转换为归一化的。
$$
\begin{aligned}
p(x\mid \theta) = \frac{1}{Z(\theta)}q(x\mid \theta)\\
\text{where: } Z(\theta) = \int q(x\mid \theta) dx
\end{aligned}
$$但是归一化系数 $Z(\theta) = \int q(x\mid \theta) dx$ 对于高维分布几乎是不可能直接计算的。我们希望能找到一些办法，避免对归一化系数的直接计算，Noise Contrastive Estimation 就是为此而提出的一种方法。（当然，其他方法还可以参考 Score Matching 和 使用神经网路进行数据生成）
2. 通过比较来估计密度（Density Estimation by Comparison）
当我们希望从一系列离散的，从一个未知分布的采样 $\{X\}_n$ 估计出具体的分布时，我们几乎一定会去提取分布的中特征。或者换句话说，我们是通过刻画分布的性质来估计未知分布的密度的。甚至可以说刻画其性质是第一性的。因此一个显然的思路是，如果我们提供一个已知的、与目标分布显著不同的噪声分布 $p_n(x)$。之后训练一个神经网络，用于区分数据来自于数据分布 $p_d(x)$ 还是噪声分布 $p_n(x)$，神经网络自然而然的就学习到了数据分布的特征。这个过程实质上就实现了数据生成的目标，即学习数据的潜在分布。而这个过程则将原本的无监督学习转换为一个简单的，有负样本的，简单的而分类问题。换句话说，NCE不直接估计概率密度，而是通过学习区分“真实数据”和“人工产生的噪声”来间接地学习模型参数。">
<meta name="author" content="WangJV">
<link rel="canonical" href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/noise-contrastive-estimation/">
<link crossorigin="anonymous" href="https://wangjv0812.github.io/WangJV-Blog-Pages/assets/css/stylesheet.8fe10233a706bc87f2e08b3cf97b8bd4c0a80f10675a143675d59212121037c0.css" integrity="sha256-j&#43;ECM6cGvIfy4Is8&#43;XuL1MCoDxBnWhQ2ddWSEhIQN8A=" rel="preload stylesheet" as="style">
<link rel="icon" href="https://wangjv0812.github.io/WangJV-Blog-Pages/favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="https://wangjv0812.github.io/WangJV-Blog-Pages/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://wangjv0812.github.io/WangJV-Blog-Pages/favicon-32x32.png">
<link rel="apple-touch-icon" href="https://wangjv0812.github.io/WangJV-Blog-Pages/apple-touch-icon.png">
<link rel="mask-icon" href="https://wangjv0812.github.io/WangJV-Blog-Pages/safari-pinned-tab.svg">
<meta name="theme-color" content="#2e2e33">
<meta name="msapplication-TileColor" content="#2e2e33">
<link rel="alternate" hreflang="en" href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/noise-contrastive-estimation/">
<noscript>
    <style>
        #theme-toggle,
        .top-link {
            display: none;
        }

    </style>
    <style>
        @media (prefers-color-scheme: dark) {
            :root {
                --theme: rgb(29, 30, 32);
                --entry: rgb(46, 46, 51);
                --primary: rgb(218, 218, 219);
                --secondary: rgb(155, 156, 157);
                --tertiary: rgb(65, 66, 68);
                --content: rgb(196, 196, 197);
                --code-block-bg: rgb(46, 46, 51);
                --code-bg: rgb(55, 56, 62);
                --border: rgb(51, 51, 51);
            }

            .list {
                background: var(--theme);
            }

            .list:not(.dark)::-webkit-scrollbar-track {
                background: 0 0;
            }

            .list:not(.dark)::-webkit-scrollbar-thumb {
                border-color: var(--theme);
            }
        }

    </style>
</noscript><script>
  MathJax = {
    tex: {
      displayMath: [['\\[', '\\]'], ['$$', '$$']],
      inlineMath: [['\\(', '\\)'], ['$', '$']],
      processEscapes: true,
      processEnvironments: true,
      tags: 'ams'
    },
    chtml: {
      scale: 1,                     
      minScale: 0.5,               
      matchFontHeight: false,       
      displayAlign: 'center',       
      displayIndent: '0',           
      mtextInheritFont: false,      
      merrorInheritFont: true,      
      mathmlSpacing: false,         
      skipHtmlTags: ['script','noscript','style','textarea','pre','code','a'],
      ignoreHtmlClass: 'tex2jax_ignore',
      processHtmlClass: 'tex2jax_process'
    },
    svg: {
      scale: 1,                     
      minScale: 0.5,               
      mtextInheritFont: false,      
      merrorInheritFont: true,
      mathmlSpacing: false,
      skipHtmlTags: ['script','noscript','style','textarea','pre','code','a'],
      ignoreHtmlClass: 'tex2jax_ignore',
      processHtmlClass: 'tex2jax_process'
    },
    options: {
      enableMenu: true,             
      menuOptions: {
        settings: {
          zoom: 'Click'             
        }
      }
    },
    loader: {
      load: ['ui/safe', 'a11y/assistive-mml']
    },
    startup: {
      ready() {
        MathJax.startup.defaultReady();
        
        const observer = new ResizeObserver(entries => {
          MathJax.typesetPromise();
        });
        observer.observe(document.body);
      }
    }
  };
  
  
  if (window.innerWidth <= 768) {
    MathJax.chtml = MathJax.chtml || {};
    MathJax.chtml.scale = 0.9;  
  }
</script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>


<style>
   
  .MathJax {
    outline: 0;
  }
  
   
  @media (max-width: 768px) {
    .MathJax {
      font-size: 90% !important;
    }
    
     
    .MathJax_Display {
      overflow-x: auto;
      overflow-y: hidden;
      padding: 0 !important;
      margin: 1em 0 !important;
    }
    
     
    .MathJax_CHTML {
      line-height: 1.2 !important;
    }
  }
  
   
  mjx-container[jax="CHTML"][display="true"] {
    overflow-x: auto;
    overflow-y: hidden;
    padding: 1px 0;
  }
</style><meta property="og:url" content="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/noise-contrastive-estimation/">
  <meta property="og:site_name" content="WangJV Blog">
  <meta property="og:title" content="Noise Contrastive Estimation">
  <meta property="og:description" content="1. 动机 在无监督学习时，我们往往都需要处理维度非常大的数据。例如无监督学习的一个经典案例：图像生成。对于一个尺寸为 $1920 \times 1080$ 的图片，其像素总量为 $2073600$，生成一张这样的照片时，我们需要对一个维度为 $2073600$ 的随机分布建模和采样。这些维度之间不可能是完全独立的，这个原因很显然，如果所有的维度完全独立，生成的数据就是完全随机的，不会包含任何信息。相邻像素的颜色、纹理高度相关，真正需要被建模的自由度远小于像素个数
可以说，我们希望通过无监督学习学习到的数据之间的规律，就建模在数据维度之间的约束中，或者换一个更常用的说法，数据之间的规律。由于数据维度之间约束的存在，数据的维度一定是小于（甚至可以说远远小于）其随机向量的维度。我们希望建模的数据事实上存在于一个高维空间上的流形上，而无监督学习实质上是通过神经网络，建模这个高位空间中数据分布的流形。
有了上面的理解，原本的如何从数据中挖掘关系这个问题就被转换为如何对数据所在的流形建模。这个问题并不容易，流形的复杂性和高维数据的稀疏性都给建模带来了挑战。目前一个主流的思路是通过概率分布对流形建模。显然，概率分布可以很方便的表达流形上的几何结构；对于一个维度为 $d$ 的概率分布，可以理解为一个从 $R^d \to R$ 的映射，当然这个映射需要满足非负和归一化。那么对于不属于流形上的点，映射到 $0$ 就好了。当然，概率分布带给我们的好处远不止于此：
概率分布本身可以很方便的处理噪声，可以很方便的用于处理真实的，带噪声的真实数据。 概率分布的采样和优化十分方便，有很多现成的研究成果 概率分布本身赋予流形一个 “软边界”。这让模型的泛化能力有保障。 但是概率模型依然不是完美的。一般而言，我们假设存在一个理想分布 $p_d(x)$，它表达了完美的，真实的数据的分布。这是一个 “可望而不可达” 的理想分布，我们所用的数据集 $x_1, x_2, \cdots x_n$ 可以认为从分布 $p_d(x)$ 中做的采样。（一种柏拉图式的哲学）。我们希望可以通过一个受到参数 $\theta$ 控制的模型分布 $p(x, \theta)$ 来逼近和代替真实分布 $p_d(x)$。
我们的神经网络不可能直接建模非归一化模型，模型本身几乎一定是非归一化的。假设我们只能建模一个非归一化模型 $q(x\mid \theta)$，则需要通过归一化系数将其转换为归一化的。
$$ \begin{aligned} p(x\mid \theta) = \frac{1}{Z(\theta)}q(x\mid \theta)\\ \text{where: } Z(\theta) = \int q(x\mid \theta) dx \end{aligned} $$但是归一化系数 $Z(\theta) = \int q(x\mid \theta) dx$ 对于高维分布几乎是不可能直接计算的。我们希望能找到一些办法，避免对归一化系数的直接计算，Noise Contrastive Estimation 就是为此而提出的一种方法。（当然，其他方法还可以参考 Score Matching 和 使用神经网路进行数据生成）
2. 通过比较来估计密度（Density Estimation by Comparison） 当我们希望从一系列离散的，从一个未知分布的采样 $\{X\}_n$ 估计出具体的分布时，我们几乎一定会去提取分布的中特征。或者换句话说，我们是通过刻画分布的性质来估计未知分布的密度的。甚至可以说刻画其性质是第一性的。因此一个显然的思路是，如果我们提供一个已知的、与目标分布显著不同的噪声分布 $p_n(x)$。之后训练一个神经网络，用于区分数据来自于数据分布 $p_d(x)$ 还是噪声分布 $p_n(x)$，神经网络自然而然的就学习到了数据分布的特征。这个过程实质上就实现了数据生成的目标，即学习数据的潜在分布。而这个过程则将原本的无监督学习转换为一个简单的，有负样本的，简单的而分类问题。换句话说，NCE不直接估计概率密度，而是通过学习区分“真实数据”和“人工产生的噪声”来间接地学习模型参数。">
  <meta property="og:locale" content="en-us">
  <meta property="og:type" content="article">
    <meta property="article:section" content="posts">
    <meta property="article:published_time" content="2025-08-18T18:08:56+08:00">
    <meta property="article:modified_time" content="2025-08-18T18:08:56+08:00">
    <meta property="article:tag" content="Unsupervised Learning">
    <meta property="article:tag" content="对比学习">
      <meta property="og:image" content="https://wangjv0812.github.io/WangJV-Blog-Pages/">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://wangjv0812.github.io/WangJV-Blog-Pages/">
<meta name="twitter:title" content="Noise Contrastive Estimation">
<meta name="twitter:description" content="1. 动机
在无监督学习时，我们往往都需要处理维度非常大的数据。例如无监督学习的一个经典案例：图像生成。对于一个尺寸为 $1920 \times 1080$ 的图片，其像素总量为 $2073600$，生成一张这样的照片时，我们需要对一个维度为 $2073600$ 的随机分布建模和采样。这些维度之间不可能是完全独立的，这个原因很显然，如果所有的维度完全独立，生成的数据就是完全随机的，不会包含任何信息。相邻像素的颜色、纹理高度相关，真正需要被建模的自由度远小于像素个数
可以说，我们希望通过无监督学习学习到的数据之间的规律，就建模在数据维度之间的约束中，或者换一个更常用的说法，数据之间的规律。由于数据维度之间约束的存在，数据的维度一定是小于（甚至可以说远远小于）其随机向量的维度。我们希望建模的数据事实上存在于一个高维空间上的流形上，而无监督学习实质上是通过神经网络，建模这个高位空间中数据分布的流形。
有了上面的理解，原本的如何从数据中挖掘关系这个问题就被转换为如何对数据所在的流形建模。这个问题并不容易，流形的复杂性和高维数据的稀疏性都给建模带来了挑战。目前一个主流的思路是通过概率分布对流形建模。显然，概率分布可以很方便的表达流形上的几何结构；对于一个维度为 $d$ 的概率分布，可以理解为一个从 $R^d \to R$ 的映射，当然这个映射需要满足非负和归一化。那么对于不属于流形上的点，映射到 $0$ 就好了。当然，概率分布带给我们的好处远不止于此：

概率分布本身可以很方便的处理噪声，可以很方便的用于处理真实的，带噪声的真实数据。
概率分布的采样和优化十分方便，有很多现成的研究成果
概率分布本身赋予流形一个 “软边界”。这让模型的泛化能力有保障。

但是概率模型依然不是完美的。一般而言，我们假设存在一个理想分布 $p_d(x)$，它表达了完美的，真实的数据的分布。这是一个 “可望而不可达” 的理想分布，我们所用的数据集 $x_1, x_2, \cdots x_n$ 可以认为从分布 $p_d(x)$ 中做的采样。（一种柏拉图式的哲学）。我们希望可以通过一个受到参数 $\theta$ 控制的模型分布 $p(x, \theta)$ 来逼近和代替真实分布 $p_d(x)$。
我们的神经网络不可能直接建模非归一化模型，模型本身几乎一定是非归一化的。假设我们只能建模一个非归一化模型 $q(x\mid \theta)$，则需要通过归一化系数将其转换为归一化的。
$$
\begin{aligned}
p(x\mid \theta) = \frac{1}{Z(\theta)}q(x\mid \theta)\\
\text{where: } Z(\theta) = \int q(x\mid \theta) dx
\end{aligned}
$$但是归一化系数 $Z(\theta) = \int q(x\mid \theta) dx$ 对于高维分布几乎是不可能直接计算的。我们希望能找到一些办法，避免对归一化系数的直接计算，Noise Contrastive Estimation 就是为此而提出的一种方法。（当然，其他方法还可以参考 Score Matching 和 使用神经网路进行数据生成）
2. 通过比较来估计密度（Density Estimation by Comparison）
当我们希望从一系列离散的，从一个未知分布的采样 $\{X\}_n$ 估计出具体的分布时，我们几乎一定会去提取分布的中特征。或者换句话说，我们是通过刻画分布的性质来估计未知分布的密度的。甚至可以说刻画其性质是第一性的。因此一个显然的思路是，如果我们提供一个已知的、与目标分布显著不同的噪声分布 $p_n(x)$。之后训练一个神经网络，用于区分数据来自于数据分布 $p_d(x)$ 还是噪声分布 $p_n(x)$，神经网络自然而然的就学习到了数据分布的特征。这个过程实质上就实现了数据生成的目标，即学习数据的潜在分布。而这个过程则将原本的无监督学习转换为一个简单的，有负样本的，简单的而分类问题。换句话说，NCE不直接估计概率密度，而是通过学习区分“真实数据”和“人工产生的噪声”来间接地学习模型参数。">


<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position":  1 ,
      "name": "Posts",
      "item": "https://wangjv0812.github.io/WangJV-Blog-Pages/posts/"
    }, 
    {
      "@type": "ListItem",
      "position":  2 ,
      "name": "Noise Contrastive Estimation",
      "item": "https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/noise-contrastive-estimation/"
    }
  ]
}
</script>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Noise Contrastive Estimation",
  "name": "Noise Contrastive Estimation",
  "description": "1. 动机 在无监督学习时，我们往往都需要处理维度非常大的数据。例如无监督学习的一个经典案例：图像生成。对于一个尺寸为 $1920 \\times 1080$ 的图片，其像素总量为 $2073600$，生成一张这样的照片时，我们需要对一个维度为 $2073600$ 的随机分布建模和采样。这些维度之间不可能是完全独立的，这个原因很显然，如果所有的维度完全独立，生成的数据就是完全随机的，不会包含任何信息。相邻像素的颜色、纹理高度相关，真正需要被建模的自由度远小于像素个数\n可以说，我们希望通过无监督学习学习到的数据之间的规律，就建模在数据维度之间的约束中，或者换一个更常用的说法，数据之间的规律。由于数据维度之间约束的存在，数据的维度一定是小于（甚至可以说远远小于）其随机向量的维度。我们希望建模的数据事实上存在于一个高维空间上的流形上，而无监督学习实质上是通过神经网络，建模这个高位空间中数据分布的流形。\n有了上面的理解，原本的如何从数据中挖掘关系这个问题就被转换为如何对数据所在的流形建模。这个问题并不容易，流形的复杂性和高维数据的稀疏性都给建模带来了挑战。目前一个主流的思路是通过概率分布对流形建模。显然，概率分布可以很方便的表达流形上的几何结构；对于一个维度为 $d$ 的概率分布，可以理解为一个从 $R^d \\to R$ 的映射，当然这个映射需要满足非负和归一化。那么对于不属于流形上的点，映射到 $0$ 就好了。当然，概率分布带给我们的好处远不止于此：\n概率分布本身可以很方便的处理噪声，可以很方便的用于处理真实的，带噪声的真实数据。 概率分布的采样和优化十分方便，有很多现成的研究成果 概率分布本身赋予流形一个 “软边界”。这让模型的泛化能力有保障。 但是概率模型依然不是完美的。一般而言，我们假设存在一个理想分布 $p_d(x)$，它表达了完美的，真实的数据的分布。这是一个 “可望而不可达” 的理想分布，我们所用的数据集 $x_1, x_2, \\cdots x_n$ 可以认为从分布 $p_d(x)$ 中做的采样。（一种柏拉图式的哲学）。我们希望可以通过一个受到参数 $\\theta$ 控制的模型分布 $p(x, \\theta)$ 来逼近和代替真实分布 $p_d(x)$。\n我们的神经网络不可能直接建模非归一化模型，模型本身几乎一定是非归一化的。假设我们只能建模一个非归一化模型 $q(x\\mid \\theta)$，则需要通过归一化系数将其转换为归一化的。\n$$ \\begin{aligned} p(x\\mid \\theta) = \\frac{1}{Z(\\theta)}q(x\\mid \\theta)\\\\ \\text{where: } Z(\\theta) = \\int q(x\\mid \\theta) dx \\end{aligned} $$但是归一化系数 $Z(\\theta) = \\int q(x\\mid \\theta) dx$ 对于高维分布几乎是不可能直接计算的。我们希望能找到一些办法，避免对归一化系数的直接计算，Noise Contrastive Estimation 就是为此而提出的一种方法。（当然，其他方法还可以参考 Score Matching 和 使用神经网路进行数据生成）\n2. 通过比较来估计密度（Density Estimation by Comparison） 当我们希望从一系列离散的，从一个未知分布的采样 $\\{X\\}_n$ 估计出具体的分布时，我们几乎一定会去提取分布的中特征。或者换句话说，我们是通过刻画分布的性质来估计未知分布的密度的。甚至可以说刻画其性质是第一性的。因此一个显然的思路是，如果我们提供一个已知的、与目标分布显著不同的噪声分布 $p_n(x)$。之后训练一个神经网络，用于区分数据来自于数据分布 $p_d(x)$ 还是噪声分布 $p_n(x)$，神经网络自然而然的就学习到了数据分布的特征。这个过程实质上就实现了数据生成的目标，即学习数据的潜在分布。而这个过程则将原本的无监督学习转换为一个简单的，有负样本的，简单的而分类问题。换句话说，NCE不直接估计概率密度，而是通过学习区分“真实数据”和“人工产生的噪声”来间接地学习模型参数。\n",
  "keywords": [
    "unsupervised learning", "对比学习"
  ],
  "articleBody": "1. 动机 在无监督学习时，我们往往都需要处理维度非常大的数据。例如无监督学习的一个经典案例：图像生成。对于一个尺寸为 $1920 \\times 1080$ 的图片，其像素总量为 $2073600$，生成一张这样的照片时，我们需要对一个维度为 $2073600$ 的随机分布建模和采样。这些维度之间不可能是完全独立的，这个原因很显然，如果所有的维度完全独立，生成的数据就是完全随机的，不会包含任何信息。相邻像素的颜色、纹理高度相关，真正需要被建模的自由度远小于像素个数\n可以说，我们希望通过无监督学习学习到的数据之间的规律，就建模在数据维度之间的约束中，或者换一个更常用的说法，数据之间的规律。由于数据维度之间约束的存在，数据的维度一定是小于（甚至可以说远远小于）其随机向量的维度。我们希望建模的数据事实上存在于一个高维空间上的流形上，而无监督学习实质上是通过神经网络，建模这个高位空间中数据分布的流形。\n有了上面的理解，原本的如何从数据中挖掘关系这个问题就被转换为如何对数据所在的流形建模。这个问题并不容易，流形的复杂性和高维数据的稀疏性都给建模带来了挑战。目前一个主流的思路是通过概率分布对流形建模。显然，概率分布可以很方便的表达流形上的几何结构；对于一个维度为 $d$ 的概率分布，可以理解为一个从 $R^d \\to R$ 的映射，当然这个映射需要满足非负和归一化。那么对于不属于流形上的点，映射到 $0$ 就好了。当然，概率分布带给我们的好处远不止于此：\n概率分布本身可以很方便的处理噪声，可以很方便的用于处理真实的，带噪声的真实数据。 概率分布的采样和优化十分方便，有很多现成的研究成果 概率分布本身赋予流形一个 “软边界”。这让模型的泛化能力有保障。 但是概率模型依然不是完美的。一般而言，我们假设存在一个理想分布 $p_d(x)$，它表达了完美的，真实的数据的分布。这是一个 “可望而不可达” 的理想分布，我们所用的数据集 $x_1, x_2, \\cdots x_n$ 可以认为从分布 $p_d(x)$ 中做的采样。（一种柏拉图式的哲学）。我们希望可以通过一个受到参数 $\\theta$ 控制的模型分布 $p(x, \\theta)$ 来逼近和代替真实分布 $p_d(x)$。\n我们的神经网络不可能直接建模非归一化模型，模型本身几乎一定是非归一化的。假设我们只能建模一个非归一化模型 $q(x\\mid \\theta)$，则需要通过归一化系数将其转换为归一化的。\n$$ \\begin{aligned} p(x\\mid \\theta) = \\frac{1}{Z(\\theta)}q(x\\mid \\theta)\\\\ \\text{where: } Z(\\theta) = \\int q(x\\mid \\theta) dx \\end{aligned} $$但是归一化系数 $Z(\\theta) = \\int q(x\\mid \\theta) dx$ 对于高维分布几乎是不可能直接计算的。我们希望能找到一些办法，避免对归一化系数的直接计算，Noise Contrastive Estimation 就是为此而提出的一种方法。（当然，其他方法还可以参考 Score Matching 和 使用神经网路进行数据生成）\n2. 通过比较来估计密度（Density Estimation by Comparison） 当我们希望从一系列离散的，从一个未知分布的采样 $\\{X\\}_n$ 估计出具体的分布时，我们几乎一定会去提取分布的中特征。或者换句话说，我们是通过刻画分布的性质来估计未知分布的密度的。甚至可以说刻画其性质是第一性的。因此一个显然的思路是，如果我们提供一个已知的、与目标分布显著不同的噪声分布 $p_n(x)$。之后训练一个神经网络，用于区分数据来自于数据分布 $p_d(x)$ 还是噪声分布 $p_n(x)$，神经网络自然而然的就学习到了数据分布的特征。这个过程实质上就实现了数据生成的目标，即学习数据的潜在分布。而这个过程则将原本的无监督学习转换为一个简单的，有负样本的，简单的而分类问题。换句话说，NCE不直接估计概率密度，而是通过学习区分“真实数据”和“人工产生的噪声”来间接地学习模型参数。\n更具体的说，我们可以证明，这个二分类问题的边界受到 $\\frac{p_d(x)}{p_n(x)}$ 控制。在我们对 $p_n(x)$ 有清晰的认知的情况下，$p_d(x)$ 是可以直接计算的。\n2.1. 的动机和推导 我们有来自于数据分布 $p_d(x)$ 的一组采样 $\\{X\\} = \\{X_1, X_2, \\cdots X_n\\}$ 和来自于噪声分布 $p_n(x)$ 的一组采样 $\\{Y\\} = \\{Y_1, Y_2, \\cdots, Y_m\\}$。来自数据和来自噪声的采样的比例有 $\\nu = \\frac{m}{n}$。将数据 $\\{X\\},\\{Y\\}$ 混合，得到新数据集 $\\{U\\} = \\{X\\} \\cup \\{Y\\}$。从中任意抽取一个数据点，如果属于采样 $\\{X\\}$，那么认为标签为 $D = 1$ (Real)，否则为 $D = 0$ (Noise)。\n根据贝叶斯定理，有：\n$$ \\begin{aligned} p(D = 1 \\mid x) = \\frac{p(x\\mid D = 1) p(D = 1)}{p(x)}\\\\ p(D = 0 \\mid x) = \\frac{p(x\\mid D = 0) p(D = 0)}{p(x)} \\end{aligned} $$现在，我们的任务是求出上面的每一项，这件事并不难：\n目标 形式 直观 $p(x\\mid D = 1)$ $p_d(x)$ 已知数据标签下数据的分布 $p(x\\mid D = 0)$ $p_n(x)$ 已知噪声标签下噪声的分布 $p(D = 1)$ $\\frac{1}{\\nu + 1}$ 任取数据，得到标签 1 的概率 $p(D = 0)$ $\\frac{\\nu}{\\nu + 1}$ 任取数据，得到标签 0 的概率 $p(x)$ $\\frac{1}{\\nu + 1}p_d(x) + \\frac{\\nu}{\\nu + 1}p_n(x)$ 混合分布 代入之前提到的贝叶斯形式，有：\n$$ \\begin{aligned} p(D = 1 \\mid x) = \\frac{p_d(x)}{p_d(x) + \\nu p_n(x)}\\\\ p(D = 0 \\mid x) = \\frac{\\nu p_n(x)}{p_d(x) + \\nu p_n(x)}\\\\ \\end{aligned} $$那么，对于一个二分类问题，一个天然的边界是看对比后验概率 $p(D = 1 \\mid x)$ 和 $p(D = 0 \\mid x)$ 谁的概率大。如果 $p(D = 1 \\mid x)$ 概率更大则认为是数据。不妨取其比值：\n$$ \\frac{p(D = 1 \\mid x)}{p(D = 0 \\mid x)} = \\frac{p_d(x)}{\\nu p_n(x)} $$针对这个分类问题，这是一个天然的 Score Function，等于 $1$ 时，恰好是分类问题的边界。这恰好是我们希望的形式，我们说过，解释了为什么我们前面说分类问题的边界受到 $\\frac{p_d(x)}{p_n(x)}$ 控制。但是这个形式我们仍然无法直接处理，不妨用一个经典 Trick，取对数：\n$$ \\ln \\left[\\frac{p(D = 1 \\mid x)}{p(D = 0 \\mid x)}\\right] = \\ln p_d(x) - \\ln p_n(x) - \\ln \\nu $$2.2. 参数化 此时，形式中包含一个无法处理的、我们假设的数据分布 $p_d(x)$，不妨用一个受到参数 $\\theta$ 控制的非归一化模型代替：\n$$ p_d(x) \\simeq \\frac{f(x, \\theta)}{Z(\\theta)} $$其中，$Z(\\theta)$ 是归一化参数，如果你还记得第一章中的介绍，这个参数是我们进行无监督学习中的巨大阻碍。我们先将该形式代入概率比值的形式中，并定义 $c = - \\ln Z(\\theta)$，并将其作为一个学习的参数：\n$$ \\begin{aligned} \\ln \\left[\\frac{p(D = 1 \\mid x)}{p(D = 0 \\mid x)}\\right] \u0026\\simeq \\ln \\left[\\frac{p(D = 1 \\mid x, \\theta)}{p(D = 0 \\mid x)}\\right]\\\\ \u0026=\\ln f(x, \\theta) + c - \\ln p_n(x) - \\ln \\nu\\\\ \u0026= G(x, \\theta, c) \\end{aligned} $$其中的 $G(x, \\theta, c)$ 就是我们要学习的得分函数，可以通过一个神经网络描述。通过 sigmoid 函数可以恢复后验概率：\n$$ p(D=1 \\mid x, \\theta) = \\sigma(G(x, \\theta, c)) = \\frac{1}{1 - \\exp\\left[-G(x, \\theta, c)\\right]} $$2.3. 构建损失函数 不妨假设标签之间独立，这个而分类问题可以直接通过一个交叉熵损失来训练。假设存在：\n$$ \\begin{aligned} J(\\theta, c) \u0026= \\sum_{i = 0}^{m + n}\\left[ D_t \\ln p(D = 1 \\mid x_i, \\theta) + (1 - D_t) \\ln p(D = 0 \\mid x_i, \\theta) \\right] \\\\ \u0026= \\sum_{i = 0}^{m + n}\\left[ D_t \\ln p(D = 1 \\mid x_i, \\theta) + (1 - D_t) \\ln \\left[ 1 - p(D = 1 \\mid x_i, \\theta) \\right]\\right] \\\\ \\end{aligned} $$代入我们学习的 Score Function $G(x, \\theta, c)$，有：\n$$ \\begin{aligned} `J(\\theta, c) `\u0026= \\frac{1}{T_d}\\sum_{i = 0}^{n}\\bigg\\{ \\ln \\sigma(G(x, \\theta, c)) \\bigg\\} + \\frac{1}{T_d}\\sum_{i = 0}^{m} \\bigg\\{\\ln \\big[ 1 - \\sigma(G(y_i, \\theta, c)) \\big]\\bigg\\}\\\\ \u0026= \\boxed{\\frac{1}{T_d}\\sum_{i = 0}^{n}\\bigg\\{ \\ln \\sigma(G(x, \\theta, c)) \\bigg\\} + \\nu \\frac{1}{T_n}\\sum_{i = 0}^{m} \\bigg\\{\\ln \\big[ 1 - \\sigma(G(y_i, \\theta, c)) \\big]\\bigg\\}} \\end{aligned} $$通过优化 $J(\\theta, c)$，就可以训练 $G(x, \\theta, c)$ 了。\n2.4. 估计的性质 问题似乎解决了，但是事实并非如此。不难发现，在解决归一化参数时我们挖了一个大坑。我们直接将归一化参数作为一个可学习参数交给优化器优化了。但是优化优化模型参数时的一个隐藏假设是所有待优化参数都是独立的。可事实并非如此，归一化参数隐藏了一个约束假设: $Z(\\theta) = \\int_{x\\in R^n} f(x, \\theta) dx$。我们希望通过优化 $J(\\theta, c)$ 我们希望对 $c$ 可以提供了一个对 $\\ln Z(\\theta)$ 的好的估计。粗暴的假设其独立，不引入约束直接优化，如何保证优化结果可以满足收到积分形式约束呢？\n事实上，从数学上可以证明，在理想条件下（数据集无限，噪声样本无限），上面的目标函数 $J(\\theta, c)$ 的极值 $(\\hat \\theta, \\hat c)$ 满足：\n$\\hat \\theta$ 是使得 $p_m(\\mathbf{x}; \\theta)$ 最接近 $p_d(\\mathbf{x})$ 的参数（即最大似然估计的解）。 $\\hat c$ 是 $-\\ln Z(\\theta)$ 的估计最优的参数。 下面我们证明这个结论。\n3. 最优性证明 推导之前，我们不妨再化简一下上面的形式，对于 $1 - \\sigma(G(y, \\theta, c))$，有：\n$$ \\begin{aligned} 1 - \\sigma(G(y, \\theta, c)) \u0026= 1 - \\frac{1}{1 + \\exp\\left[-G(y, \\theta, c)\\right]}\\\\ \u0026= \\frac{\\exp\\left[-G(y, \\theta, c)\\right]}{1 + \\exp\\left[-G(y, \\theta, c)\\right]}\\\\ \u0026= \\frac{1}{1 + \\exp\\left[G(y, \\theta, c)\\right]}\\\\ \u0026= \\sigma(-G(y, \\theta, c)) \\end{aligned} $$当有 $m \\to \\infty, n \\to \\infty$ 时，有：\n$$ \\begin{aligned} \\frac{1}{T_d}\\sum_{i = 0}^{n}\\bigg\\{\\ln \\sigma(G(x, \\theta, c)) \\bigg\\} \u0026= \\mathbb{E}_{x\\sim p_d(x)}\\big[ \\ln \\sigma(G(x, \\theta, c))\\big]\\\\ \\frac{1}{T_n}\\sum_{i = 0}^{m} \\ln \\big[1 - \\sigma(G(y_i, \\theta, c))\\big] \u0026= \\mathbb{E}_{y\\sim p_n(y)}\\big[ \\ln \\big[- \\sigma(G(y, \\theta, c))\\big]\\big]\\\\ \\end{aligned} $$那么有：\n$$ J(\\theta, c) = \\mathbb{E}_{x\\sim p_d(x)}\\big[ \\ln \\sigma(G(x, \\theta, c))\\big] + \\nu \\mathbb{E}_{y\\sim p_n(y)}\\big[ \\ln \\big[-\\sigma(G(y, \\theta, c))\\big]\\big] $$不妨令上式对 $c$ 求导：\n$$ \\begin{aligned} \\frac{\\partial J(\\theta, c)}{\\partial c} \u0026= \\mathbb{E}_{x\\sim p_d(x)}\\big[ \\frac{\\partial}{\\partial c}\\ln \\sigma(G(x, \\theta, c))\\big] + \\nu \\mathbb{E}_{y\\sim p_n(y)}\\big[\\frac{\\partial}{\\partial c} \\ln \\big[- \\sigma(G(y, \\theta, c))\\big]\\big]\\\\ \u0026= \\mathbb{E}_{x \\sim p_d}\\left[ \\frac{1}{\\sigma(G)} \\cdot \\sigma(G)(1-\\sigma(G)) \\cdot \\frac{\\partial G}{\\partial c} \\right] + \\nu \\mathbb{E}_{y \\sim p_n}\\left[ \\frac{1}{\\sigma(-G)} \\cdot (-\\sigma(-G)(1-\\sigma(-G))) \\cdot \\frac{\\partial G}{\\partial c} \\right]\\\\ \u0026= \\mathbb{E}_{x \\sim p_d}\\left[ (1-\\sigma(G(x))) \\cdot \\frac{\\partial G}{\\partial c} \\right] + \\nu \\mathbb{E}_{y \\sim p_n}\\left[ - (1-\\sigma(-G(y))) \\cdot \\frac{\\partial G}{\\partial c} \\right] \\end{aligned} $$对于 $\\frac{\\partial G}{\\partial c}$，有：\n$$ \\begin{aligned} \\frac{\\partial G}{\\partial c} \u0026= \\frac{\\partial\\ln f(x, \\theta) + c - \\ln p_n(x) - \\ln \\nu}{\\partial c}\\\\ \u0026= 1 \\end{aligned} $$代入上式，并用 $1 - \\sigma(G) = \\sigma(-G)$ 替换，有：\n$$ \\begin{aligned} \\frac{\\partial J(\\theta, c)}{\\partial c} \u0026= \\mathbb{E}_{x \\sim p_d}\\bigg[ 1 - \\sigma(G(x)) \\bigg] - \\nu \\mathbb{E}_{y \\sim p_n}\\bigg[\\sigma(G(y)) \\bigg] \\end{aligned} $$对于优化极值，应有上式为 $0$，可得：\n$$ \\mathbb{E}_{x \\sim p_d}\\big[1 - \\sigma(G(x)) \\big] = \\nu \\mathbb{E}_{y \\sim p_n}\\big[\\sigma(G(y)) \\big] $$不妨将 $G(x)$ 的具体形式代入，有：\n$$ \\sigma(G(x)) = \\frac{1}{1 + \\exp(-G(x))} = \\frac{1}{1 + \\frac{\\nu p_n(\\mathbf{x}) e^{-c}}{f(\\mathbf{x};\\theta)}} $$有：\n$$ \\begin{aligned} \\mathbb{E}_{x \\sim p_d}\\big[1 - \\sigma(G(x)) \\big] \u0026= \\mathbb{E}_{x \\sim p_d} \\big[ \\frac{\\nu p_n(x)}{\\frac{f(x, \\theta)}{e^{-c}} + \\nu p_n(x)}\\big]\\\\ \\mathbb{E}_{y \\sim p_n}\\big[\\sigma(G(y)) \\big] \u0026= \\mathbb{E}_{y \\sim p_n}\\big[ \\frac{\\frac{f(x, \\theta)}{e^{-c}}}{\\frac{f(x, \\theta)}{e^{-c}} + \\nu p_n(x)} \\big] \\end{aligned} $$将期望符号展开为积分形式：\n$$ \\begin{aligned} \\mathbb{E}_{x \\sim p_d} \\big[ \\frac{\\nu p_n(x)}{\\frac{f(x, \\theta)}{e^{-c}} + \\nu p_n(x)}\\big] \u0026= \\int \\frac{p_d(x)\\nu p_n(x)}{\\frac{f(x, \\theta)}{e^{-c}} + \\nu p_n(x)} dx\\\\ \\nu\\mathbb{E}_{y \\sim p_n}\\big[ \\frac{\\frac{f(x, \\theta)}{e^{-c}}}{\\frac{f(x, \\theta)}{e^{-c}} + \\nu p_n(x)} \\big] \u0026= \\int \\frac{\\nu p_n(x)\\frac{f(x, \\theta)}{e^{-c}}}{\\frac{f(x, \\theta)}{e^{-c}} + \\nu p_n(x)}dx \\end{aligned} $$对比上下两个形式，其相等的一个充分条件为：\n$$ \\begin{aligned} \\frac{p_d(x)\\nu p_n(x)}{\\frac{f(x, \\theta)}{e^{-c}} + \\nu p_n(x)} \u0026= \\frac{\\nu p_n(x)\\frac{f(x, \\theta)}{e^{-c}}}{\\frac{f(x, \\theta)}{e^{-c}} + \\nu p_n(x)}\\\\ p_d(x) \u0026= \\frac{f(x, \\theta)}{e^{-c}} \\end{aligned} $$Cool，我们完成了证明。所以，只要达到最优，就可以认为训练出的归一化参数是满足归一化性质的。\n4. 讨论 下面我们解决一些 NCE 的细节。主要想讨论两个点：\n在选择噪声时应该如何考虑 NCE 和 负样本学习的关系 4.1. 如何选择噪声 对于噪声选择，可以总结出下面几个原则：\n我们最好可以选择一个 $\\ln p_n(x)$ 有优雅解析形式的噪声 我们最好可以找到一个与数据分布 $p_d(x)$ 有一定相似性的噪声。因为 NCE 本质还是一个二分类问题，如果噪声与数据差距过大，任务会变得过于简单，导致学不到数据的内在特征。最优的噪声应使最优分类器的错误率接近 50%，这迫使模型可以学习数据特征的细节。 噪声需要可以覆盖数据分布 $p_d(x)$ 的支撑集。如果覆盖不全，对于某些数据点 $\\mathbf{x} \\sim p_d$，如果 $p_n(\\mathbf{x}) = 0$，那么在计算 $G(\\mathbf{x}) = \\ln f(\\mathbf{x};\\theta) + c - \\ln p_n(\\mathbf{x}) - \\ln \\nu$ 时，$\\ln p_n(\\mathbf{x})$ 会趋于 $-\\infty$，导致 $G(\\mathbf{x}) \\to +\\infty$。这使得 $\\sigma(G(\\mathbf{x})) \\approx 1$，模型无需学习就会给这些点非常高的分数，破坏了学习过程。 噪声最好有高方差：一个方差较大的 $p_n(\\mathbf{x})$（例如方差较大的高斯分布）通常比一个方差很小的分布更好。因为它更有可能产生一些“ challenging negatives”，即那些与真实数据点很接近的噪声样本，这有助于模型学习更精细的决策边界。 我们还可以不加证明的给出一个理论性的分析：\nNCE 的渐近正态性：$\\sqrt{T_d}(\\hat \\theta_T -\\theta^*)$ 服从渐近正态分布，其均值为 $0$，协方差矩阵为 $\\Sigma$，即：\n$$ \\Sigma = I^{-1}_\\nu - \\left(1 + \\frac{1}{\\nu}\\right) I^{-1}_\\nu E(P_\\nu g) E(P_\\nu g)^T I^{-1}_\\nu $$其中，$E(P_\\nu g) = \\int P_\\nu (u)g(u)p_d(u)du$。\n4.2. 与负采样（Negative Sampling）的关系 负采样（NEG） 是 NCE 的一个特例和近似。NCE 的原始目标是同时估计密度模型和归一化常数。而 Mikolov 等人提出的 NEG 做了一个关键的简化：\n它固定 $c = 0$（即完全假设模型是自我归一化的，$Z=1$）。 它修改了目标函数，不再精确等价于对数似然最大化。 NEG 的目标是： $$ J_{\\text{NEG}}(\\theta) = \\sum_{t=1}^{T} \\left[\\begin{array}{l} \\ln \\sigma(\\ln f(\\mathbf{x}_t; \\theta) - \\ln p_n(\\mathbf{x}_t) - \\ln k) \\\\+ \\sum_{j=1}^{k} \\ln \\sigma(-(\\ln f(\\mathbf{y}_{t,j}; \\theta) - \\ln p_n(\\mathbf{y}_{t,j}) - \\ln k)) \\end{array}\\right] $$NEG 的计算更简单，并且在像词向量学习这样的任务中效果非常好，但它不再是一个严格正确的最大似然估计器。可以认为 NEG 是 NCE 的一种高效、实用的工程近似。\n4.3. 梯度如何驱动 $c$ 最直观的理解方式是：\n参数 $c$ 在模型的对数概率 $\\ln p_m(x; \\theta, c) = \\ln f(x, \\theta) + c$ 中，充当一个全局的偏置（bias）。 如果 $c$ 太大，会导致模型 $p_m$ 的值整体偏高。在分类任务中，这意味着模型会过于自信地将所有样本（包括噪声样本）都判断为真实数据（$D=1$）。这会导致在噪声样本上的损失（即 $-\\ln(1-\\sigma)$ 部分）变得非常大。为了降低总损失，优化算法必须减小 $c$。 如果 $c$ 太小，会导致模型 $p_m$ 的值整体偏低。这意味着模型会倾向于将所有样本（包括真实数据）都判断为噪声（$D=0$）。这会导致在真实数据上的损失（即 $-\\ln \\sigma$ 部分）变得非常大。为了降低总损失，优化算法必须增大 $c$。 因此，优化过程本身形成了一个负反馈循环。损失函数通过“惩罚”在噪声样本上的过度自信和在真实样本上的不自信，迫使参数 $c$ 进行调整。这个调整的最终平衡点在哪里？\n就是当 $p_m(x; \\hat{\\theta}, \\hat{c})$ 在分布上与 $p_d(x)$ 完全一致时。此时，$\\frac{p_m(x; \\hat{\\theta}, \\hat{c})}{p_n(x)} = \\frac{p_d(x)}{p_n(x)}$，分类器达到了贝叶斯最优分类器的形态，总损失达到最小。而当 $p_m = p_d$ 时，必然意味着模型已经正确归一化，即 $e^{\\hat{c}} \\int f(x, \\hat{\\theta}) dx = \\int p_d(x) dx = 1$。 由此可得 $e^{\\hat{c}} Z(\\hat{\\theta}) = 1$，即 $\\hat{c} = -\\ln Z(\\hat{\\theta})$。\n总结一下，这个保证归一化的数学结构是一个以“区分真实与噪声”为目标的对抗性/对比性框架，其中归一化常数（或其对数）作为分类器的一个可学习偏置项。优化该分类器的损失函数，会内在地、非直接地迫使该偏置项收敛到能使模型概率分布有效的正确值。\nReference @article{10.5555/2188385.2188396, author = {Gutmann, Michael U. and Hyv\"{a}rinen, Aapo}, title = {Noise-contrastive estimation of unnormalized statistical models, with applications to natural image statistics}, year = {2012}, issue_date = {3/1/2012}, publisher = {JMLR.org}, volume = {13}, number = {null}, issn = {1532-4435}, journal = {J. Mach. Learn. Res.}, month = feb, pages = {307–361}, numpages = {55}, keywords = {computation, estimation, natural image statistics, partition function, unnormalized models} }\n",
  "wordCount" : "1181",
  "inLanguage": "en",
  "image": "https://wangjv0812.github.io/WangJV-Blog-Pages/","datePublished": "2025-08-18T18:08:56+08:00",
  "dateModified": "2025-08-18T18:08:56+08:00",
  "author":{
    "@type": "Person",
    "name": "WangJV"
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/noise-contrastive-estimation/"
  },
  "publisher": {
    "@type": "Organization",
    "name": "WangJV Blog",
    "logo": {
      "@type": "ImageObject",
      "url": "https://wangjv0812.github.io/WangJV-Blog-Pages/favicon.ico"
    }
  }
}
</script>
</head>

<body class="" id="top">
<script>
    if (localStorage.getItem("pref-theme") === "dark") {
        document.body.classList.add('dark');
    } else if (localStorage.getItem("pref-theme") === "light") {
        document.body.classList.remove('dark')
    } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
        document.body.classList.add('dark');
    }

</script>

<header class="header">
    <nav class="nav">
        <div class="logo">
            <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/" accesskey="h" title="WangJV Blog (Alt + H)">WangJV Blog</a>
            <div class="logo-switches">
                <button id="theme-toggle" accesskey="t" title="(Alt + T)" aria-label="Toggle theme">
                    <svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
                        fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                        stroke-linejoin="round">
                        <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
                    </svg>
                    <svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
                        fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                        stroke-linejoin="round">
                        <circle cx="12" cy="12" r="5"></circle>
                        <line x1="12" y1="1" x2="12" y2="3"></line>
                        <line x1="12" y1="21" x2="12" y2="23"></line>
                        <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
                        <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
                        <line x1="1" y1="12" x2="3" y2="12"></line>
                        <line x1="21" y1="12" x2="23" y2="12"></line>
                        <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
                        <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
                    </svg>
                </button>
            </div>
        </div>
        <ul id="menu">
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/" title="Home">
                    <span>Home</span>
                </a>
            </li>
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/posts/" title="Posts">
                    <span>Posts</span>
                </a>
            </li>
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/archives/" title="Archive">
                    <span>Archive</span>
                </a>
            </li>
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/tags/" title="Tags">
                    <span>Tags</span>
                </a>
            </li>
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/search/" title="🔍 Search (Alt &#43; /)" accesskey=/>
                    <span>🔍 Search</span>
                </a>
            </li>
        </ul>
    </nav>
</header>
<main class="main">

<article class="post-single">
  <header class="post-header">
    <div class="breadcrumbs"><a href="https://wangjv0812.github.io/WangJV-Blog-Pages/">Home</a>&nbsp;»&nbsp;<a href="https://wangjv0812.github.io/WangJV-Blog-Pages/posts/">Posts</a></div>
    <h1 class="post-title entry-hint-parent">
      Noise Contrastive Estimation
    </h1>
    <div class="post-meta"><span title='2025-08-18 18:08:56 +0800 CST'>August 18, 2025</span>&nbsp;·&nbsp;6 min&nbsp;·&nbsp;1181 words&nbsp;·&nbsp;WangJV&nbsp;|&nbsp;<a href="https://github.com/WangJV0812/WangJV-Blog-Source/tree/master/content/posts/Noise%20Contrastive%20Estimation/index.md" rel="noopener noreferrer edit" target="_blank">Suggest Changes</a>

</div>
  </header> <div class="toc">
    <details >
        <summary accesskey="c" title="(Alt + C)">
            <span class="details">Table of Contents</span>
        </summary>

        <div class="inner"><nav id="TableOfContents">
  <ul>
    <li><a href="#1-动机">1. 动机</a></li>
    <li><a href="#2-通过比较来估计密度density-estimation-by-comparison">2. 通过比较来估计密度（Density Estimation by Comparison）</a>
      <ul>
        <li><a href="#21-的动机和推导">2.1. 的动机和推导</a></li>
        <li><a href="#22-参数化">2.2. 参数化</a></li>
      </ul>
    </li>
    <li><a href="#23-构建损失函数">2.3. 构建损失函数</a>
      <ul>
        <li><a href="#24-估计的性质">2.4. 估计的性质</a></li>
      </ul>
    </li>
    <li><a href="#3-最优性证明">3. 最优性证明</a></li>
    <li><a href="#4-讨论">4. 讨论</a>
      <ul>
        <li><a href="#41-如何选择噪声">4.1. 如何选择噪声</a></li>
        <li><a href="#42-与负采样negative-sampling的关系">4.2. 与负采样（Negative Sampling）的关系</a></li>
        <li><a href="#43-梯度如何驱动">4.3. 梯度如何驱动 </a></li>
      </ul>
    </li>
    <li><a href="#reference">Reference</a></li>
  </ul>
</nav>
        </div>
    </details>
</div>

  <div class="post-content"><h2 id="1-动机">1. 动机<a hidden class="anchor" aria-hidden="true" href="#1-动机">#</a></h2>
<p>在无监督学习时，我们往往都需要处理维度非常大的数据。例如无监督学习的一个经典案例：图像生成。对于一个尺寸为 $1920 \times 1080$ 的图片，其像素总量为 $2073600$，生成一张这样的照片时，我们需要对一个维度为 $2073600$ 的随机分布建模和采样。这些维度之间不可能是完全独立的，这个原因很显然，如果所有的维度完全独立，生成的数据就是完全随机的，不会包含任何信息。相邻像素的颜色、纹理高度相关，真正需要被建模的自由度远小于像素个数</p>
<p>可以说，我们希望通过无监督学习学习到的数据之间的规律，就建模在数据维度之间的约束中，或者换一个更常用的说法，数据之间的规律。由于数据维度之间约束的存在，数据的维度一定是小于（甚至可以说远远小于）其随机向量的维度。我们希望建模的数据事实上存在于一个高维空间上的流形上，而无监督学习实质上是通过神经网络，建模这个高位空间中数据分布的流形。</p>
<p>有了上面的理解，原本的如何从数据中挖掘关系这个问题就被转换为如何对数据所在的流形建模。这个问题并不容易，流形的复杂性和高维数据的稀疏性都给建模带来了挑战。目前一个主流的思路是通过概率分布对流形建模。显然，概率分布可以很方便的表达流形上的几何结构；对于一个维度为 $d$ 的概率分布，可以理解为一个从 $R^d \to R$ 的映射，当然这个映射需要满足非负和归一化。那么对于不属于流形上的点，映射到 $0$ 就好了。当然，概率分布带给我们的好处远不止于此：</p>
<ol>
<li>概率分布本身可以很方便的处理噪声，可以很方便的用于处理真实的，带噪声的真实数据。</li>
<li>概率分布的采样和优化十分方便，有很多现成的研究成果</li>
<li>概率分布本身赋予流形一个 “软边界”。这让模型的泛化能力有保障。</li>
</ol>
<p>但是概率模型依然不是完美的。一般而言，我们假设存在一个理想分布 $p_d(x)$，它表达了完美的，真实的数据的分布。这是一个 “可望而不可达” 的理想分布，我们所用的数据集 $x_1, x_2, \cdots x_n$ 可以认为从分布 $p_d(x)$ 中做的采样。（一种柏拉图式的哲学）。我们希望可以通过一个受到参数 $\theta$ 控制的模型分布 $p(x, \theta)$ 来逼近和代替真实分布 $p_d(x)$。</p>
<p>我们的神经网络不可能直接建模非归一化模型，模型本身几乎一定是非归一化的。假设我们只能建模一个非归一化模型 $q(x\mid \theta)$，则需要通过归一化系数将其转换为归一化的。</p>
$$
\begin{aligned}
p(x\mid \theta) = \frac{1}{Z(\theta)}q(x\mid \theta)\\
\text{where: } Z(\theta) = \int q(x\mid \theta) dx
\end{aligned}
$$<p>但是归一化系数 $Z(\theta) = \int q(x\mid \theta) dx$ 对于高维分布几乎是不可能直接计算的。我们希望能找到一些办法，避免对归一化系数的直接计算，<code>Noise Contrastive Estimation</code> 就是为此而提出的一种方法。（当然，其他方法还可以参考 <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/scorematching/">Score Matching</a> 和 <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/2024/12/dreamfusion/#1-%E4%BD%BF%E7%94%A8%E7%A5%9E%E7%BB%8F%E7%BD%91%E8%B7%AF%E8%BF%9B%E8%A1%8C%E6%95%B0%E6%8D%AE%E7%94%9F%E6%88%90">使用神经网路进行数据生成</a>）</p>
<h2 id="2-通过比较来估计密度density-estimation-by-comparison">2. 通过比较来估计密度（Density Estimation by Comparison）<a hidden class="anchor" aria-hidden="true" href="#2-通过比较来估计密度density-estimation-by-comparison">#</a></h2>
<p>当我们希望从一系列离散的，从一个未知分布的采样 $\{X\}_n$ 估计出具体的分布时，我们几乎一定会去提取分布的中特征。或者换句话说，我们是通过刻画分布的性质来估计未知分布的密度的。甚至可以说刻画其性质是第一性的。因此一个显然的思路是，如果我们提供一个已知的、与目标分布显著不同的噪声分布 $p_n(x)$。之后训练一个神经网络，用于区分数据来自于数据分布 $p_d(x)$ 还是噪声分布 $p_n(x)$，神经网络自然而然的就学习到了数据分布的特征。这个过程实质上就实现了数据生成的目标，即学习数据的潜在分布。而这个过程则将原本的无监督学习转换为一个简单的，有负样本的，简单的而分类问题。换句话说，<strong>NCE不直接估计概率密度，而是通过学习区分“真实数据”和“人工产生的噪声”来间接地学习模型参数。</strong></p>
<p>更具体的说，我们可以证明，这个二分类问题的边界受到 $\frac{p_d(x)}{p_n(x)}$ 控制。在我们对 $p_n(x)$ 有清晰的认知的情况下，$p_d(x)$ 是可以直接计算的。</p>
<h3 id="21-的动机和推导">2.1. 的动机和推导<a hidden class="anchor" aria-hidden="true" href="#21-的动机和推导">#</a></h3>
<p>我们有来自于数据分布 $p_d(x)$ 的一组采样 $\{X\} = \{X_1, X_2, \cdots X_n\}$ 和来自于噪声分布 $p_n(x)$ 的一组采样 $\{Y\} = \{Y_1, Y_2, \cdots, Y_m\}$。来自数据和来自噪声的采样的比例有 $\nu = \frac{m}{n}$。将数据 $\{X\},\{Y\}$ 混合，得到新数据集 $\{U\} = \{X\} \cup \{Y\}$。从中任意抽取一个数据点，如果属于采样 $\{X\}$，那么认为标签为 $D = 1$ (Real)，否则为 $D = 0$ (Noise)。</p>
<p>根据贝叶斯定理，有：</p>
$$
\begin{aligned}
p(D = 1 \mid x) = \frac{p(x\mid D = 1) p(D = 1)}{p(x)}\\
p(D = 0 \mid x) = \frac{p(x\mid D = 0) p(D = 0)}{p(x)}
\end{aligned}
$$<p>现在，我们的任务是求出上面的每一项，这件事并不难：</p>
<table>
  <thead>
      <tr>
          <th>目标</th>
          <th>形式</th>
          <th>直观</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>$p(x\mid D = 1)$</td>
          <td>$p_d(x)$</td>
          <td>已知数据标签下数据的分布</td>
      </tr>
      <tr>
          <td>$p(x\mid D = 0)$</td>
          <td>$p_n(x)$</td>
          <td>已知噪声标签下噪声的分布</td>
      </tr>
      <tr>
          <td>$p(D = 1)$</td>
          <td>$\frac{1}{\nu + 1}$</td>
          <td>任取数据，得到标签 1 的概率</td>
      </tr>
      <tr>
          <td>$p(D = 0)$</td>
          <td>$\frac{\nu}{\nu + 1}$</td>
          <td>任取数据，得到标签 0 的概率</td>
      </tr>
      <tr>
          <td>$p(x)$</td>
          <td>$\frac{1}{\nu + 1}p_d(x) + \frac{\nu}{\nu + 1}p_n(x)$</td>
          <td>混合分布</td>
      </tr>
  </tbody>
</table>
<p>代入之前提到的贝叶斯形式，有：</p>
$$
\begin{aligned}
p(D = 1 \mid x) = \frac{p_d(x)}{p_d(x) + \nu p_n(x)}\\
p(D = 0 \mid x) = \frac{\nu p_n(x)}{p_d(x) + \nu p_n(x)}\\
\end{aligned}
$$<p>那么，对于一个二分类问题，一个天然的边界是看对比后验概率 $p(D = 1 \mid x)$ 和 $p(D = 0 \mid x)$ 谁的概率大。如果 $p(D = 1 \mid x)$ 概率更大则认为是数据。不妨取其比值：</p>
$$
\frac{p(D = 1 \mid x)}{p(D = 0 \mid x)} = \frac{p_d(x)}{\nu p_n(x)}
$$<p>针对这个分类问题，这是一个天然的 Score Function，等于 $1$ 时，恰好是分类问题的边界。这恰好是我们希望的形式，我们说过，解释了为什么我们前面说分类问题的边界受到 $\frac{p_d(x)}{p_n(x)}$ 控制。但是这个形式我们仍然无法直接处理，不妨用一个经典 Trick，取对数：</p>
$$
\ln \left[\frac{p(D = 1 \mid x)}{p(D = 0 \mid x)}\right] = \ln p_d(x) - \ln p_n(x) - \ln \nu
$$<h3 id="22-参数化">2.2. 参数化<a hidden class="anchor" aria-hidden="true" href="#22-参数化">#</a></h3>
<p>此时，形式中包含一个无法处理的、我们假设的数据分布 $p_d(x)$，不妨用一个受到参数 $\theta$ 控制的非归一化模型代替：</p>
$$
p_d(x) \simeq \frac{f(x, \theta)}{Z(\theta)}
$$<p>其中，$Z(\theta)$ 是归一化参数，如果你还记得第一章中的介绍，这个参数是我们进行无监督学习中的巨大阻碍。我们先将该形式代入概率比值的形式中，并定义 $c = - \ln Z(\theta)$，并将其作为一个学习的参数：</p>
$$
\begin{aligned}
\ln \left[\frac{p(D = 1 \mid x)}{p(D = 0 \mid x)}\right]
&\simeq \ln \left[\frac{p(D = 1 \mid x, \theta)}{p(D = 0 \mid x)}\right]\\
&=\ln f(x, \theta) + c - \ln p_n(x) - \ln \nu\\
&= G(x, \theta, c)
\end{aligned}
$$<p>其中的 $G(x, \theta, c)$ 就是我们要学习的得分函数，可以通过一个神经网络描述。通过 sigmoid 函数可以恢复后验概率：</p>
$$
p(D=1 \mid x, \theta) = \sigma(G(x, \theta, c)) = \frac{1}{1 - \exp\left[-G(x, \theta, c)\right]}
$$<h2 id="23-构建损失函数">2.3. 构建损失函数<a hidden class="anchor" aria-hidden="true" href="#23-构建损失函数">#</a></h2>
<p>不妨假设标签之间独立，这个而分类问题可以直接通过一个交叉熵损失来训练。假设存在：</p>
$$
\begin{aligned}
J(\theta, c)
&= \sum_{i = 0}^{m + n}\left[
D_t \ln p(D = 1 \mid x_i, \theta) + (1 - D_t) \ln p(D = 0 \mid x_i, \theta)
\right] \\
&= \sum_{i = 0}^{m + n}\left[
D_t \ln p(D = 1 \mid x_i, \theta) + (1 - D_t) \ln \left[
1 - p(D = 1 \mid x_i, \theta)
\right]\right] \\
\end{aligned}
$$<p>代入我们学习的 Score Function $G(x, \theta, c)$，有：</p>
$$
\begin{aligned}
`J(\theta, c)
`&= \frac{1}{T_d}\sum_{i = 0}^{n}\bigg\{
\ln \sigma(G(x, \theta, c)) \bigg\} + \frac{1}{T_d}\sum_{i = 0}^{m} \bigg\{\ln \big[
1 - \sigma(G(y_i, \theta, c))
\big]\bigg\}\\
&= \boxed{\frac{1}{T_d}\sum_{i = 0}^{n}\bigg\{
\ln \sigma(G(x, \theta, c)) \bigg\} + \nu \frac{1}{T_n}\sum_{i = 0}^{m} \bigg\{\ln \big[
1 - \sigma(G(y_i, \theta, c))
\big]\bigg\}}
\end{aligned}
$$<p>通过优化 $J(\theta, c)$，就可以训练 $G(x, \theta, c)$ 了。</p>
<h3 id="24-估计的性质">2.4. 估计的性质<a hidden class="anchor" aria-hidden="true" href="#24-估计的性质">#</a></h3>
<p>问题似乎解决了，但是事实并非如此。不难发现，在解决归一化参数时我们挖了一个大坑。我们直接将归一化参数作为一个可学习参数交给优化器优化了。但是优化优化模型参数时的一个隐藏假设是所有待优化参数都是独立的。可事实并非如此，归一化参数隐藏了一个约束假设: $Z(\theta) = \int_{x\in R^n} f(x, \theta) dx$。我们希望通过优化 $J(\theta, c)$ 我们希望对 $c$ 可以提供了一个对 $\ln Z(\theta)$ 的好的估计。粗暴的假设其独立，不引入约束直接优化，如何保证优化结果可以满足收到积分形式约束呢？</p>
<p>事实上，从数学上可以证明，在理想条件下（数据集无限，噪声样本无限），上面的目标函数 $J(\theta, c)$ 的极值 $(\hat \theta, \hat c)$ 满足：</p>
<ol>
<li>$\hat \theta$ 是使得 $p_m(\mathbf{x}; \theta)$ 最接近 $p_d(\mathbf{x})$ 的参数（即最大似然估计的解）。</li>
<li>$\hat c$ 是 $-\ln Z(\theta)$ 的估计最优的参数。</li>
</ol>
<p>下面我们证明这个结论。</p>
<h2 id="3-最优性证明">3. 最优性证明<a hidden class="anchor" aria-hidden="true" href="#3-最优性证明">#</a></h2>
<p>推导之前，我们不妨再化简一下上面的形式，对于 $1 - \sigma(G(y, \theta, c))$，有：</p>
$$
\begin{aligned}
1 - \sigma(G(y, \theta, c))
&= 1 - \frac{1}{1 + \exp\left[-G(y, \theta, c)\right]}\\
&= \frac{\exp\left[-G(y, \theta, c)\right]}{1 + \exp\left[-G(y, \theta, c)\right]}\\
&= \frac{1}{1 + \exp\left[G(y, \theta, c)\right]}\\
&= \sigma(-G(y, \theta, c))
\end{aligned}
$$<p>当有 $m \to \infty, n \to \infty$ 时，有：</p>
$$
\begin{aligned}
\frac{1}{T_d}\sum_{i = 0}^{n}\bigg\{\ln \sigma(G(x, \theta, c)) \bigg\}
&= \mathbb{E}_{x\sim p_d(x)}\big[ \ln \sigma(G(x, \theta, c))\big]\\
\frac{1}{T_n}\sum_{i = 0}^{m} \ln \big[1 - \sigma(G(y_i, \theta, c))\big]
&= \mathbb{E}_{y\sim p_n(y)}\big[ \ln \big[- \sigma(G(y, \theta, c))\big]\big]\\
\end{aligned}
$$<p>那么有：</p>
$$
J(\theta, c) = \mathbb{E}_{x\sim p_d(x)}\big[ \ln \sigma(G(x, \theta, c))\big] + \nu \mathbb{E}_{y\sim p_n(y)}\big[ \ln \big[-\sigma(G(y, \theta, c))\big]\big]
$$<p>不妨令上式对 $c$ 求导：</p>
$$
\begin{aligned}
\frac{\partial J(\theta, c)}{\partial c}
&= \mathbb{E}_{x\sim p_d(x)}\big[ \frac{\partial}{\partial c}\ln \sigma(G(x, \theta, c))\big] + \nu \mathbb{E}_{y\sim p_n(y)}\big[\frac{\partial}{\partial c} \ln \big[- \sigma(G(y, \theta, c))\big]\big]\\
&= \mathbb{E}_{x \sim p_d}\left[ \frac{1}{\sigma(G)} \cdot \sigma(G)(1-\sigma(G)) \cdot \frac{\partial G}{\partial c} \right] + \nu \mathbb{E}_{y \sim p_n}\left[ \frac{1}{\sigma(-G)} \cdot (-\sigma(-G)(1-\sigma(-G))) \cdot \frac{\partial G}{\partial c} \right]\\
&= \mathbb{E}_{x \sim p_d}\left[ (1-\sigma(G(x))) \cdot \frac{\partial G}{\partial c} \right] + \nu \mathbb{E}_{y \sim p_n}\left[ - (1-\sigma(-G(y))) \cdot \frac{\partial G}{\partial c} \right]
\end{aligned}
$$<p>对于 $\frac{\partial G}{\partial c}$，有：</p>
$$
\begin{aligned}
\frac{\partial G}{\partial c}
&= \frac{\partial\ln f(x, \theta) + c - \ln p_n(x) - \ln \nu}{\partial c}\\
&= 1
\end{aligned}
$$<p>代入上式，并用 $1 - \sigma(G) = \sigma(-G)$ 替换，有：</p>
$$
\begin{aligned}
\frac{\partial J(\theta, c)}{\partial c}
&= \mathbb{E}_{x \sim p_d}\bigg[ 1 - \sigma(G(x)) \bigg] - \nu \mathbb{E}_{y \sim p_n}\bigg[\sigma(G(y)) \bigg]
\end{aligned}
$$<p>对于优化极值，应有上式为 $0$，可得：</p>
$$
\mathbb{E}_{x \sim p_d}\big[1 - \sigma(G(x)) \big] = \nu \mathbb{E}_{y \sim p_n}\big[\sigma(G(y)) \big]
$$<p>不妨将 $G(x)$ 的具体形式代入，有：</p>
$$
\sigma(G(x)) = \frac{1}{1 + \exp(-G(x))} = \frac{1}{1 + \frac{\nu p_n(\mathbf{x}) e^{-c}}{f(\mathbf{x};\theta)}}
$$<p>有：</p>
$$
\begin{aligned}
\mathbb{E}_{x \sim p_d}\big[1 - \sigma(G(x)) \big]
&= \mathbb{E}_{x \sim p_d} \big[ \frac{\nu p_n(x)}{\frac{f(x, \theta)}{e^{-c}} + \nu p_n(x)}\big]\\
\mathbb{E}_{y \sim p_n}\big[\sigma(G(y)) \big]
&= \mathbb{E}_{y \sim p_n}\big[ \frac{\frac{f(x, \theta)}{e^{-c}}}{\frac{f(x, \theta)}{e^{-c}} + \nu p_n(x)} \big]
\end{aligned}
$$<p>将期望符号展开为积分形式：</p>
$$
\begin{aligned}
\mathbb{E}_{x \sim p_d} \big[ \frac{\nu p_n(x)}{\frac{f(x, \theta)}{e^{-c}} + \nu p_n(x)}\big]
&= \int \frac{p_d(x)\nu p_n(x)}{\frac{f(x, \theta)}{e^{-c}} + \nu p_n(x)} dx\\
\nu\mathbb{E}_{y \sim p_n}\big[ \frac{\frac{f(x, \theta)}{e^{-c}}}{\frac{f(x, \theta)}{e^{-c}} + \nu p_n(x)} \big]
&= \int \frac{\nu p_n(x)\frac{f(x, \theta)}{e^{-c}}}{\frac{f(x, \theta)}{e^{-c}} + \nu p_n(x)}dx
\end{aligned}
$$<p>对比上下两个形式，其相等的一个充分条件为：</p>
$$
\begin{aligned}
\frac{p_d(x)\nu p_n(x)}{\frac{f(x, \theta)}{e^{-c}} + \nu p_n(x)}
&= \frac{\nu p_n(x)\frac{f(x, \theta)}{e^{-c}}}{\frac{f(x, \theta)}{e^{-c}} + \nu p_n(x)}\\
p_d(x) &= \frac{f(x, \theta)}{e^{-c}}
\end{aligned}
$$<p>Cool，我们完成了证明。所以，只要达到最优，就可以认为训练出的归一化参数是满足归一化性质的。</p>
<h2 id="4-讨论">4. 讨论<a hidden class="anchor" aria-hidden="true" href="#4-讨论">#</a></h2>
<p>下面我们解决一些 NCE 的细节。主要想讨论两个点：</p>
<ol>
<li>在选择噪声时应该如何考虑</li>
<li>NCE 和 负样本学习的关系</li>
</ol>
<h3 id="41-如何选择噪声">4.1. 如何选择噪声<a hidden class="anchor" aria-hidden="true" href="#41-如何选择噪声">#</a></h3>
<p>对于噪声选择，可以总结出下面几个原则：</p>
<ol>
<li>我们最好可以选择一个 $\ln p_n(x)$ 有优雅解析形式的噪声</li>
<li>我们最好可以找到一个与数据分布 $p_d(x)$ 有一定相似性的噪声。因为 NCE 本质还是一个二分类问题，如果噪声与数据差距过大，任务会变得过于简单，导致学不到数据的内在特征。最优的噪声应使最优分类器的错误率接近 50%，这迫使模型可以学习数据特征的细节。</li>
<li>噪声需要可以覆盖数据分布 $p_d(x)$ 的支撑集。如果覆盖不全，对于某些数据点 $\mathbf{x} \sim p_d$，如果 $p_n(\mathbf{x}) = 0$，那么在计算 $G(\mathbf{x}) = \ln f(\mathbf{x};\theta) + c - \ln p_n(\mathbf{x}) - \ln \nu$ 时，$\ln p_n(\mathbf{x})$ 会趋于 $-\infty$，导致 $G(\mathbf{x}) \to +\infty$。这使得 $\sigma(G(\mathbf{x})) \approx 1$，模型无需学习就会给这些点非常高的分数，破坏了学习过程。</li>
<li>噪声最好有高方差：一个方差较大的 $p_n(\mathbf{x})$（例如方差较大的高斯分布）通常比一个方差很小的分布更好。因为它更有可能产生一些“ challenging negatives”，即那些与真实数据点很接近的噪声样本，这有助于模型学习更精细的决策边界。</li>
</ol>
<p>我们还可以不加证明的给出一个理论性的分析：</p>
<p>NCE 的渐近正态性：$\sqrt{T_d}(\hat \theta_T -\theta^*)$ 服从渐近正态分布，其均值为 $0$，协方差矩阵为 $\Sigma$，即：</p>
$$
\Sigma = I^{-1}_\nu - \left(1 + \frac{1}{\nu}\right) I^{-1}_\nu E(P_\nu g) E(P_\nu g)^T I^{-1}_\nu
$$<p>其中，$E(P_\nu g) = \int P_\nu (u)g(u)p_d(u)du$。</p>
<h3 id="42-与负采样negative-sampling的关系">4.2. 与负采样（Negative Sampling）的关系<a hidden class="anchor" aria-hidden="true" href="#42-与负采样negative-sampling的关系">#</a></h3>
<p><strong>负采样（NEG）</strong> 是 NCE 的一个特例和近似。NCE 的原始目标是<strong>同时估计密度模型和归一化常数</strong>。而 Mikolov 等人提出的 NEG 做了一个关键的简化：</p>
<ul>
<li><strong>它固定 $c = 0$</strong>（即完全假设模型是自我归一化的，$Z=1$）。</li>
<li>它<strong>修改了目标函数</strong>，不再精确等价于对数似然最大化。</li>
</ul>
<p>NEG 的目标是：
</p>
$$
J_{\text{NEG}}(\theta) = \sum_{t=1}^{T} \left[\begin{array}{l} \ln \sigma(\ln f(\mathbf{x}_t; \theta) - \ln p_n(\mathbf{x}_t) - \ln k) \\+ \sum_{j=1}^{k} \ln \sigma(-(\ln f(\mathbf{y}_{t,j}; \theta) - \ln p_n(\mathbf{y}_{t,j}) - \ln k)) \end{array}\right]
$$<p>NEG 的计算更简单，并且在像词向量学习这样的任务中效果非常好，但它不再是一个严格正确的最大似然估计器。<strong>可以认为 NEG 是 NCE 的一种高效、实用的工程近似。</strong></p>
<h3 id="43-梯度如何驱动">4.3. 梯度如何驱动 $c$<a hidden class="anchor" aria-hidden="true" href="#43-梯度如何驱动">#</a></h3>
<p>最直观的理解方式是：</p>
<ul>
<li>参数 $c$ 在模型的对数概率 $\ln p_m(x; \theta, c) = \ln f(x, \theta) + c$ 中，充当一个全局的偏置（bias）。</li>
<li>如果 $c$ 太大，会导致模型 $p_m$ 的值整体偏高。在分类任务中，这意味着模型会过于自信地将所有样本（包括噪声样本）都判断为真实数据（$D=1$）。这会导致在噪声样本上的损失（即 $-\ln(1-\sigma)$ 部分）变得非常大。为了降低总损失，优化算法必须减小 $c$。</li>
<li>如果 $c$ 太小，会导致模型 $p_m$ 的值整体偏低。这意味着模型会倾向于将所有样本（包括真实数据）都判断为噪声（$D=0$）。这会导致在真实数据上的损失（即 $-\ln \sigma$ 部分）变得非常大。为了降低总损失，优化算法必须增大 $c$。</li>
</ul>
<p>因此，<strong>优化过程本身形成了一个负反馈循环</strong>。损失函数通过“惩罚”在噪声样本上的过度自信和在真实样本上的不自信，迫使参数 $c$ 进行调整。这个调整的最终平衡点在哪里？</p>
<p>就是当 $p_m(x; \hat{\theta}, \hat{c})$ 在分布上与 $p_d(x)$ 完全一致时。此时，$\frac{p_m(x; \hat{\theta}, \hat{c})}{p_n(x)} = \frac{p_d(x)}{p_n(x)}$，分类器达到了贝叶斯最优分类器的形态，总损失达到最小。而当 $p_m = p_d$ 时，必然意味着模型已经正确归一化，即 $e^{\hat{c}} \int f(x, \hat{\theta}) dx = \int p_d(x) dx = 1$。
由此可得 $e^{\hat{c}} Z(\hat{\theta}) = 1$，即 $\hat{c} = -\ln Z(\hat{\theta})$。</p>
<p>总结一下，这个保证归一化的数学结构是一个以“区分真实与噪声”为目标的对抗性/对比性框架，其中归一化常数（或其对数）作为分类器的一个可学习偏置项。优化该分类器的损失函数，会内在地、非直接地迫使该偏置项收敛到能使模型概率分布有效的正确值。</p>
<h2 id="reference">Reference<a hidden class="anchor" aria-hidden="true" href="#reference">#</a></h2>
<p>@article{10.5555/2188385.2188396,
author = {Gutmann, Michael U. and Hyv&quot;{a}rinen, Aapo},
title = {Noise-contrastive estimation of unnormalized statistical models, with applications to natural image statistics},
year = {2012},
issue_date = {3/1/2012},
publisher = {JMLR.org},
volume = {13},
number = {null},
issn = {1532-4435},
journal = {J. Mach. Learn. Res.},
month = feb,
pages = {307–361},
numpages = {55},
keywords = {computation, estimation, natural image statistics, partition function, unnormalized models}
}</p>


  </div>

  <footer class="post-footer">
    <ul class="post-tags">
      <li><a href="https://wangjv0812.github.io/WangJV-Blog-Pages/tags/unsupervised-learning/">Unsupervised Learning</a></li>
      <li><a href="https://wangjv0812.github.io/WangJV-Blog-Pages/tags/%E5%AF%B9%E6%AF%94%E5%AD%A6%E4%B9%A0/">对比学习</a></li>
    </ul>
<nav class="paginav">
  <a class="next" href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/sliced-score-matching/">
    <span class="title">Next »</span>
    <br>
    <span>Sliced Score Matching</span>
  </a>
</nav>

  </footer>
</article>
    </main>
    
<footer class="footer">
        <span>&copy; 2025 <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/">WangJV Blog</a></span> · 

    <span>
        Powered by
        <a href="https://gohugo.io/" rel="noopener noreferrer" target="_blank">Hugo</a> &
        <a href="https://github.com/adityatelange/hugo-PaperMod/" rel="noopener" target="_blank">PaperMod</a>
    </span>
</footer>
<a href="#top" aria-label="go to top" title="Go to Top (Alt + G)" class="top-link" id="top-link" accesskey="g">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6" fill="currentColor">
        <path d="M12 6H0l6-6z" />
    </svg>
</a>

<script>
    let menu = document.getElementById('menu')
    if (menu) {
        menu.scrollLeft = localStorage.getItem("menu-scroll-position");
        menu.onscroll = function () {
            localStorage.setItem("menu-scroll-position", menu.scrollLeft);
        }
    }

    document.querySelectorAll('a[href^="#"]').forEach(anchor => {
        anchor.addEventListener("click", function (e) {
            e.preventDefault();
            var id = this.getAttribute("href").substr(1);
            if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
                document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView({
                    behavior: "smooth"
                });
            } else {
                document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView();
            }
            if (id === "top") {
                history.replaceState(null, null, " ");
            } else {
                history.pushState(null, null, `#${id}`);
            }
        });
    });

</script>
<script>
    var mybutton = document.getElementById("top-link");
    window.onscroll = function () {
        if (document.body.scrollTop > 800 || document.documentElement.scrollTop > 800) {
            mybutton.style.visibility = "visible";
            mybutton.style.opacity = "1";
        } else {
            mybutton.style.visibility = "hidden";
            mybutton.style.opacity = "0";
        }
    };

</script>
<script>
    document.getElementById("theme-toggle").addEventListener("click", () => {
        if (document.body.className.includes("dark")) {
            document.body.classList.remove('dark');
            localStorage.setItem("pref-theme", 'light');
        } else {
            document.body.classList.add('dark');
            localStorage.setItem("pref-theme", 'dark');
        }
    })

</script>
<script>
    document.querySelectorAll('pre > code').forEach((codeblock) => {
        const container = codeblock.parentNode.parentNode;

        const copybutton = document.createElement('button');
        copybutton.classList.add('copy-code');
        copybutton.innerHTML = 'copy';

        function copyingDone() {
            copybutton.innerHTML = 'copied!';
            setTimeout(() => {
                copybutton.innerHTML = 'copy';
            }, 2000);
        }

        copybutton.addEventListener('click', (cb) => {
            if ('clipboard' in navigator) {
                navigator.clipboard.writeText(codeblock.textContent);
                copyingDone();
                return;
            }

            const range = document.createRange();
            range.selectNodeContents(codeblock);
            const selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(range);
            try {
                document.execCommand('copy');
                copyingDone();
            } catch (e) { };
            selection.removeRange(range);
        });

        if (container.classList.contains("highlight")) {
            container.appendChild(copybutton);
        } else if (container.parentNode.firstChild == container) {
            
        } else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
            
            codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
        } else {
            
            codeblock.parentNode.appendChild(copybutton);
        }
    });
</script>
</body>

</html>
